﻿using Microsoft.Extensions.DependencyInjection;
using Modules.CheckIn.Repositories;
using Modules.CheckInCount;
using Modules.CheckInCount.Entitys;
using Modules.Project;
using Modules.Project.Entitys;
using Modules.Reports;
using Modules.System.Settings;
using Modules.System.Settings.Entitys;
using PmSoft;
using System;

namespace Modules.CheckIn
{
    [UseDI(ServiceLifetime.Scoped)]
    public class CheckinWorkHoursService
    {
        private readonly CheckinWorkHoursRepository checkinWorkHoursRepository;
        private readonly SettingManager<CheckinWageStatusSettings> settingManager;
        private readonly CheckinWageStatusSettings settings;
        private readonly CheckInCountService checkInCountService;
        private readonly ProjectGroupMemberService projectGroupMemberService;
        public CheckinWorkHoursService(CheckinWorkHoursRepository checkinWorkHoursRepository,
            SettingManager<CheckinWageStatusSettings> settingManager,
            CheckInCountService checkInCountService,
            ProjectGroupMemberService projectGroupMemberService)
        {
            this.checkinWorkHoursRepository = checkinWorkHoursRepository;
            this.settingManager = settingManager;
            this.settings = settingManager.Get();
            this.checkInCountService = checkInCountService;
            this.projectGroupMemberService = projectGroupMemberService;
        }

        /// <summary>
        /// 获取指定月份今日未更新统计的班组成员ID集合
        /// </summary>
        /// <param name="month">月份</param>
        /// <param name="limit"></param>
        /// <returns></returns>
        public IEnumerable<int> GetMemberIdsInNoUpdate(DateTime month, int limit = 100)
        {
            return checkinWorkHoursRepository.GetMemberIdsInNoUpdate(month, limit);
        }

        /// <summary>
        /// 生成
        /// </summary>
        /// <param name="memberId"></param>
        /// <param name="month">日期</param>
        public void Generate(int memberId, DateTime month)
        {
            Generate(new int[] { memberId }, month);
        }

        /// <summary>
        /// 批量生成
        /// 实现原理：从考勤计数表读取数据形成报告
        /// </summary>
        /// <param name="memberIds"></param>
        /// <param name="monthDate">日期</param>
        public void Generate(IEnumerable<int> memberIds, DateTime monthDate)
        {
            //班组人员集合指定月份考勤天数计数信息集合
            IEnumerable<CountPermonth> workDaysCountPermonths = checkInCountService.GetCountPermonths(CountTenantType.Member, CountType.WorkDays, monthDate.Year, monthDate.Month, memberIds);
            //班组人员集合指定月份上班时长计数信息集合
            IEnumerable<CountPermonth> workDurationCountPermonths = checkInCountService.GetCountPermonths(CountTenantType.Member, CountType.WorkDuration, monthDate.Year, monthDate.Month, memberIds);
            var groupMembers = projectGroupMemberService.GetProjectGroupMembers(memberIds);

            foreach (int memberId in memberIds)
            {
                var member = groupMembers.FirstOrDefault(m => m.Id == memberId);
                if (member == null)
                    continue;
                var workDaysCountPermonth = workDaysCountPermonths.FirstOrDefault(m => m.ObjectId == memberId);
                var workDurationCountPermonth = workDurationCountPermonths.FirstOrDefault(m => m.ObjectId == memberId);
                int workMin = workDurationCountPermonth?.StatisticsCount ?? 0;
                decimal duration = workMin > 0 ? workMin / 60M : 0M;//计算小时数
                CheckinWorkHours workInfo = new()
                {
                    MemberId = memberId,
                    Month = monthDate.ToMonthNumber(),
                    ProjectId = member.ProjectId,
                    PersonId = member.PersonId,
                    CorpId = member.CorpId,
                    GroupId = member.GroupId,
                    CheckinDay = workDaysCountPermonth?.StatisticsCount ?? 0,
                    WorkHours = duration
                };
                CreateOrUpdate(workInfo);
            }
        }

        /// <summary>
        /// 班组成员指定月份考勤工时统计
        /// </summary>
        /// <param name="month"></param>
        /// <param name="memberId"></param>
        /// <returns></returns>
        public CheckinWorkHours? GetCheckinWorkHoursByMonthAndMemberId(int month, int memberId)
        {
            return GetCheckinWorkHours(memberId).FirstOrDefault(m => m.Month == month);
        }

        /// <summary>
        /// 获取班组成员所有月份考勤工时统计集合
        /// </summary>
        /// <param name="memberId"></param>
        /// <returns></returns>
        public IEnumerable<CheckinWorkHours> GetCheckinWorkHours(int memberId)
        {
            return checkinWorkHoursRepository.GetCheckinWorkHours(memberId);
        }

        public IEnumerable<CheckinWorkHours> GetCheckinWorkHoursByMonthAndMemberIds(int month, IEnumerable<int> memberIds)
        {
            return checkinWorkHoursRepository.GetCheckinWorkHoursByMonthAndMemberIds(month, memberIds);
        }

        public IEnumerable<CheckinWorkHours> GetCheckinWorkHoursByMonthsAndMemberIds(IEnumerable<int> months, IEnumerable<int> memberIds, IEnumerable<int> projectIds)
        {
            return checkinWorkHoursRepository.GetCheckinWorkHoursByMonthsAndMemberIds(months, memberIds, projectIds);
        }

        public CheckinWorkHours? Get(int id)
        {
            return checkinWorkHoursRepository.Get(id);
        }

        /// <summary>
        /// 更新或创建
        /// </summary>
        /// <param name="entity"></param>
        public void CreateOrUpdate(CheckinWorkHours entity)
        {
            checkinWorkHoursRepository.CreateOrUpdate(entity);
        }

        /// <summary>
        /// 获取企业在项目下指定月份总计工天
        /// </summary>
        /// <param name="month">月份</param>
        /// <param name="projectId">项目ID</param>
        /// <param name="corpId">企业ID</param>
        /// <returns></returns>
        public int GetTotalCheckinDays(int month, int projectId, int corpId)
        {
            return checkinWorkHoursRepository.GetTotalCheckinDays(month, projectId, corpId);
        }

        /// <summary>
        /// 获取项目指定月和成员考勤天数统计信息
        /// </summary>
        /// <param name="month"></param>
        /// <param name="memberIds"></param>
        /// <returns></returns>
        public IEnumerable<CheckinWorkHours> GetCheckinWorks(int month, IEnumerable<int> memberIds)
        {
            return checkinWorkHoursRepository.GetCheckinWorks( month, memberIds);
        }

        //public IEnumerable<CheckinWorkHours> GetCheckinWorkHoursByProjectIdsAndMonth(IEnumerable<int> projectIds, string month)
        //{
        //    return checkinWorkHoursRepository.GetCheckinWorkHoursByProjectIdsAndMonth(projectIds, month);
        //}

        /// <summary>
        /// 获取考勤落实状态
        /// </summary>
        /// <param name="members"></param>
        /// <param name="checkinWorkHours"></param>
        /// <param name="projectId"></param>
        /// <param name="isManager">是否关键岗位</param>
        /// <returns></returns>
        //public 落实状态 GetKeyPositionCheckinStatus(IEnumerable<ProjectGroupMember> members, IEnumerable<CheckinWorkHours> checkinWorkHours, int projectId, bool isManager)
        //{
        //    //当月应考勤人数
        //    var noManagerMembers = members.Where(a => a.ProjectId == projectId && a.IsManager == isManager);
        //    var noManagerMemberIds = noManagerMembers.Select(a => a.Id).ToList();
        //    var thisMonthCheckinPersonCountY = noManagerMembers.Count();
        //    if (thisMonthCheckinPersonCountY > 0)
        //    {
        //        //当月实际考勤人数
        //        var thisMonthCheckinPersonCountS = checkinWorkHours.Where(a => a.ProjectId == projectId && noManagerMemberIds.Contains(a.MemberId)).Count();
        //        if (thisMonthCheckinPersonCountS == 0)
        //            return 落实状态.未落实;
        //        else
        //        {
        //            var checkinRate = Convert.ToDecimal(thisMonthCheckinPersonCountS) / Convert.ToDecimal(thisMonthCheckinPersonCountY);
        //            if (checkinRate >= settings.ImplementedValue)
        //                return 落实状态.已落实;
        //            else if (checkinRate < settings.ImplementedValue && checkinRate >= settings.SemiImplementationValue)
        //                return 落实状态.半落实;
        //            else //checkinRate==0
        //                return 落实状态.未落实;
        //        }
        //    }
        //    else return 落实状态.无需核实;
        //}
    }
}